// Copyright (C) Calum Grant 2008

#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

namespace dynamic
{
	const int dir_separator = '/';

	/// A wrapper for the POSIX filesystem calls.
	class posix_filesystem_api
	{
	public:
		static int dir_separator() { return '/'; }

		struct dir_iterator
		{
			DIR * dp;
			struct dirent ep;

			dir_iterator() : dp(0) { }
			~dir_iterator() { if(dp) closedir(dp); }
		};

		static bool first_file(std::string name, dir_iterator & data)
		{
			data.dp = opendir(name.c_str());
			if(data.dp)
			{
				struct dirent * epp;
				readdir_r(data.dp, &data.ep, &epp);
				return epp;
			}
			else
			{
				return false;
			}
		}

		static bool find_next(dir_iterator & data)
		{
			if(data.dp)
			{
				struct dirent * epp;
				readdir_r(data.dp, &data.ep, &epp);
				return epp;
			}
			else
			{
				return false;
			}
		}

		static const char * get_filename(const dir_iterator & data)
		{
			return data.ep.d_name;
		}

		static bool is_directory(const dir_iterator & data, std::string const & filename)
		{
			return is_directory(filename);
		}

		/// Performs a stat to query whether the given file is a directory.
		static bool is_directory(std::string const & filename)
		{
			struct stat mstat;
			return stat(filename.c_str(), &mstat) == 0 && S_ISDIR(mstat.st_mode);
		}
	};

	/// The platform-specific filesystem implementation.
	typedef posix_filesystem_api filesystem_api;
}
